/*
 * Copyright (C) 2012 Artem Bakulin
 *
 * This file is part of Speech Fluency for Android
 * (http://code.google.com/p/speech-fluency-droid/)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.google.code.speechfluency;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CheckedTextView;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;

/**
 * Delayed audio feedback front-end
 * 
 * @author Artem Bakulin
 */
public class SpeechFluencyActivity extends Activity {
    
    private static final int MAX_DELAY = 2;
    private static final int MAX_BOOST = 20;
    
    private CheckedTextView delayValueTextView;
    private CheckedTextView boostValueTextView;
    private SeekBar delaySeekBar;
    private SeekBar boostSeekBar;
    private CheckBox muteWithoutHeadsetCheckbox;
    private Button startStopButton;
    
    private Settings settings;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        delayValueTextView = findView(R.id.delayInSecondsValue);
        delaySeekBar = findView(R.id.delaySeekBar);
        boostValueTextView = findView(R.id.boostValue);
        boostSeekBar = findView(R.id.boostSeekBar);
        muteWithoutHeadsetCheckbox = findView(R.id.muteWithoutHeadsetCheckbox);
        startStopButton = findView(R.id.startStopButton);
        
        delaySeekBar.setOnSeekBarChangeListener(delaySeekBarListener);
        boostSeekBar.setOnSeekBarChangeListener(boostSeekBarListener);
        muteWithoutHeadsetCheckbox.setOnCheckedChangeListener(muteCheckedChangeListener);
        startStopButton.setOnClickListener(startStopButtonListener);
        
        restoreSettings();
        
        applyChanges();
    }
    
    @Override
    protected void onStop() {
        settings.dumpToPreferences(getPreferences(MODE_PRIVATE));
        super.onStop();
    }

    private void restoreSettings() {
        settings = Settings.restoreFromPreferences(getPreferences(MODE_PRIVATE));
        initDelay();
        initBoost();
        updateStartStopLabel();
        muteWithoutHeadsetCheckbox.setChecked(settings.isMuteWithoutHeadset());
    }
    
    private void toogleRecording() {
        settings.setActive(!settings.isActive());
        updateStartStopLabel();
        applyChanges();
    }
    
    private void updateStartStopLabel() {
        int label = settings.isActive()
                ? R.string.stop_label
                : R.string.start_label;
        startStopButton.setText(label);
    }
    
    private void initDelay() {
        float delay = settings.getDelayInSeconds();
        int progress = (int)(delay * delaySeekBar.getMax() / (float)MAX_DELAY);
        delaySeekBar.setProgress(progress);
        delayValueTextView.setText(Float.toString(delay));
    }
    
    private void updateDelay() {
        float delayInSeconds = delaySeekBar.getProgress() * MAX_DELAY / (float)delaySeekBar.getMax();
        settings.setDelayInSeconds(delayInSeconds);
        delayValueTextView.setText(Float.toString(delayInSeconds));
    }
    
    private void initBoost() {
        float boost = settings.getBoostInDb();
        int progress = (int)(boost * boostSeekBar.getMax() / (float)MAX_BOOST);
        boostSeekBar.setProgress(progress);
        boostValueTextView.setText(Float.toString(boost));
    }
    
    private void updateBoost() {
        float boostInDb = boostSeekBar.getProgress() * MAX_BOOST / (float)boostSeekBar.getMax();
        settings.setBoostInDb(boostInDb);
        boostValueTextView.setText(Float.toString(boostInDb));
    }
    
    private void updateMuteWithoutHeadset() {
        this.settings.setMuteWithoutHeadset(muteWithoutHeadsetCheckbox.isChecked());
        applyChanges();
    }
    
    private void applyChanges() {
        Intent intent = new Intent(this, DelayedAudioFeedbackService.class);
        settings.addToIntent(intent);
        startService(intent);
    }
    
    @SuppressWarnings("unchecked")
    private <T> T findView(int id) {
        return (T)findViewById(id);
    }
    
    private final OnClickListener startStopButtonListener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            toogleRecording();
        }
    };
    
    private final OnSeekBarChangeListener delaySeekBarListener = new OnSeekBarChangeListener() {
        
        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
            applyChanges();
        }
        
        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
            // nothing
        }
        
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            updateDelay();
        }
    };
    
    private final OnSeekBarChangeListener boostSeekBarListener = new OnSeekBarChangeListener() {
        
        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
            applyChanges();
        }
        
        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
            // nothing
        }
        
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            updateBoost();
        }
    };
    
    private final OnCheckedChangeListener muteCheckedChangeListener = new OnCheckedChangeListener() {
        
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            updateMuteWithoutHeadset();
        }
    };
}